package com.fyd.mybatis.builder.XML;

import com.fyd.mybatis.builder.BaseBuilder;
import com.fyd.mybatis.io.Resources;
import com.fyd.mybatis.mapping.MappedStatement;
import com.fyd.mybatis.mapping.SqlCommandType;
import com.fyd.mybatis.session.Configuration;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;

import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description
 * @Auther: fyd20
 * @Date: 2025/6/4 20:08
 * @Description: XMLConfigBuilder
 * @Version 1.0.0
 */
public class XMLConfigBuilder extends BaseBuilder {
    private Element root;
    public XMLConfigBuilder(Reader reader) {
        // 1. 调用父类初始化configuration
        super(new Configuration());
        // 2. dom4j 处理 xml
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(new InputSource(reader));
            root = document.getRootElement();
        }catch (DocumentException e){
            e.printStackTrace();
        }
    }

    public Configuration parse(){
        try {
            mapperElement(root.element("mappers"));
        }catch (Exception e){
            throw new RuntimeException("Error parsing SQL Mapper Configuration . Cause : "+ e,e);
        }
        return configuration;
    }

    private void mapperElement(Element mappers) throws Exception {
        // 从配置文件中取出mapper标签
        List<Element> mapperList = mappers.elements("mapper");
        for (Element e : mapperList) {
            // 从mapper标签中取出 resource的内容
            String resource = e.attributeValue("resource");
            Reader reader = Resources.getResourceAsReader(resource);
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(new InputSource(reader));
            Element root = document.getRootElement();
            // 命名空间
            String namespace = root.attributeValue("namespace");

            // select
            List<Element> selectNodes = root.elements("select");
            for (Element node : selectNodes) {
                String id = node.attributeValue("id");
                String parameterType = node.attributeValue("parameterType");
                String resultType = node.attributeValue("resultType");
                String sql = node.getText();
                // ? 匹配
                Map<Integer,String> parameter = new HashMap<>();
                Pattern pattern = Pattern.compile("(#\\{(.*?)})");
                Matcher matcher = pattern.matcher(sql);
                for (int i = 0;  matcher.find(); i++) {
                    String g1 = matcher.group(1);
                    String g2 = matcher.group(2);
                    parameter.put(i,g2);
                    sql = sql.replace(g1,"?");
                }
                String msId = namespace + "." + id;
                String nodeName = node.getName();
                SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
                MappedStatement mappedStatement = new MappedStatement
                        .Builder(
                         configuration, msId,
                        sqlCommandType, parameterType,
                        resultType, sql, parameter)
                        .build();
                // 添加解析 SQL
                configuration.addMappedStatement(mappedStatement);
            }
            // 注册Mapper映射器
            configuration.addMapper(Resources.classForName(namespace));


        }


    }

}
